package com.galudisu.player

import akka.actor.Props
import com.galudisu.ddd._
import com.galudisu.player.Player._
import spray.json.RootJsonFormat
import ServiceProtocol._

// ====== Command =======
trait PlayerCommand extends EntityCommand

case class CreatePlayer(id: String, xp: Int, credits: Int) extends PlayerCommand {
  override def entityId = id
}

// ======= Event ========
trait PlayerEvent extends EntityEvent {def entityType = "player"}

case class PlayerCreated(player: PlayerFO) extends PlayerEvent

// ======= State ========

trait PlayerState extends EntityFieldsObject[String,PlayerState]

object InitialState {
  def empty = InitialState("")
}

case class InitialState(id: String, deleted:Boolean = false) extends PlayerState {
  override def assignId(id: String) = this.copy(id)
  override def markDeleted = this
}

object PlayerFO {
  def empty = PlayerFO("", 0, 0)
  implicit val format:RootJsonFormat[PlayerFO] = jsonFormat4(PlayerFO.apply)
}
case class PlayerFO(id: String, xp:Int, credits: Int, deleted: Boolean = false) extends PlayerState {
  override def assignId(id: String) = this.copy(id = id)
  override def markDeleted = this.copy(deleted = true)
}

object Player {
  def props:Props = Props[Player]

}
class Player extends PersistentEntity[PlayerState] {

  override type Command = PlayerCommand
  override type Event = PlayerEvent
  override type State = PlayerState

  override def initialState: State = InitialState.empty

  override def additionalCommandHandling: Receive = {
    case o: CreatePlayer ⇒
      val playerFO = PlayerFO(
        id = o.id,
        xp = o.xp,
        credits = o.credits
      )
      persistAsync(PlayerCreated(playerFO))(handleEventAndRespond()) // return state

  }

  override def isCreateMessage(cmd: PlayerCommand) = cmd match {
    case cr: CreatePlayer ⇒ true
    case _ ⇒ false
  }

  // 事件改变实体的状态
  override def handleEvent(event: PlayerEvent) = event match {
    case PlayerCreated(playerFO) ⇒
      state = playerFO
  }
}
